<#assign hasStatus=false>
<#assign hasChild=false>
<#assign hasSort=false>
<#assign hasContent=false>
<#list table.fields as field>
    <#if field.propertyName=="status"><#assign hasStatus=true></#if>
    <#if field.propertyName=="parentId"><#assign hasChild=true></#if>
    <#if field.propertyName=="sortBy"><#assign hasSort=true></#if>
    <#if field.propertyName?lower_case?ends_with("content")><#assign hasContent=true></#if>
</#list>
package cn.jx.cjm.${cfg.cjmModuleName}.support;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.jx.cjm.common.base.BaseRequest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
<#if hasSort>
import cn.jx.cjm.common.base.BaseSortChange;
</#if>
<#if hasChild>
import cn.jx.cjm.common.util.ParentEntityUtils;
<#elseif table.fields!?size gt cfg.minExport>
    <#list table.fields as field>
        <#if field.propertyName?ends_with("Id") && field.propertyType == "Integer">
            <#assign optionsKey=field.propertyName?remove_ending("Id")?uncap_first/>
import cn.jx.cjm.${cfg.tableModuleMap[optionsKey]!''}.support.${field.propertyName?cap_first?replace("Id","")}SupportService;
import cn.jx.cjm.${cfg.tableModuleMap[optionsKey]!''}.dto.response.${field.propertyName?cap_first?replace("Id","")}Response;
        </#if>
    </#list>
</#if>
import cn.jx.cjm.common.aop.annotation.Lockable;
import com.baomidou.mybatisplus.extension.api.R;
import cn.jx.cjm.common.enums.BizExceptionEnum;
import cn.jx.cjm.common.exception.BizException;
import cn.jx.cjm.common.util.BeanUtils;
import cn.jx.cjm.${cfg.cjmModuleName}.dto.request.${entity}Request;
import cn.jx.cjm.${cfg.cjmModuleName}.dto.response.${entity}Response;
import ${package.Entity}.${entity};
import ${package.Service}.I${entity}Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;



import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;


/**
* ${table.comment!} 业务处理层
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${entity}SupportService {
<#assign cacheName = "CACHE_" + table.name?upper_case>

    private final static String ${cacheName} = "${"CACHE:" + table.name?upper_case}";

    @Autowired
    private I${entity}Service ${entity?uncap_first}Service;
<#if hasChild>
    @Autowired
    private ${entity}SupportService ${entity?uncap_first}SupportService;
<#elseif table.fields!?size gt cfg.minExport>
    <#list table.fields as field>
        <#if field.propertyName?ends_with("Id") && field.propertyType == "Integer">
    @Autowired
    private ${field.propertyName?cap_first?replace("Id","")}SupportService ${(field.propertyName)?replace("Id","")}SupportService;
        </#if>
    </#list>
</#if>

    /**
     * ${table.comment!} 列表
     * @param request .
     * @return .
     */
<#if hasChild>
    public List<${entity}Response> list(${entity}Request request) {
        return options(null == request ? null : request.getParentId());
    }

    //@Cacheable(cacheNames = ${cacheName}, key = "'ALL'")
    public List<${entity}Response> listAll() {
        QueryWrapper<${entity}> queryWrapper = new BaseRequest<${entity}>().getQueryWrapper(${entity}.class);
        List<${entity}> list = ${entity?uncap_first}Service.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>(0);
        }
        List<${entity}Response> responseList = new ArrayList<>();
            for (${entity} temp : list) {
            ${entity}Response response = new ${entity}Response();
            BeanUtils.copyPropertiesIgnoreNull(temp,response);
            responseList.add(response);
        }
        return responseList;
    }

    /**
     * ${table.comment!} 下拉框
     * @return
     */
    public List<${entity}Response> options(${cfg.idType} parentId) {
        List<${entity}Response> responseList = ${entity?uncap_first}SupportService.listAll();
        if (CollectionUtils.isEmpty(responseList)) {
            return new ArrayList<>(0);
        }
        ParentEntityUtils<${entity}Response> treeUtils = new ParentEntityUtils<>(responseList);
        return treeUtils.getTree(parentId);
    }
<#else>
    public IPage<${entity}Response> list(BaseRequest<${entity}> request) {
    <#if hasContent >
        QueryWrapper<${entity}> queryWrapper = request.getQueryWrapper();
        queryWrapper.select(<#list table.fields as field><#if !field.propertyName?lower_case?ends_with("content")>"${field.annotationColumnName}",</#if></#list>"create_time");
        IPage<${entity}> tempPage = ${entity?uncap_first}Service.page(request.getPage(), queryWrapper);
    <#else>
        IPage<${entity}> tempPage = ${entity?uncap_first}Service.page(request.getPage(), request.getQueryWrapper());
    </#if>


        IPage<${entity}Response> result = new Page<>();
        result.setTotal(tempPage.getTotal());
        result.setCurrent(tempPage.getCurrent());
        result.setSize(tempPage.getSize());
        result.setPages(tempPage.getPages());

        List<${entity}Response> responseList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(tempPage.getRecords())) {
            for (${entity} temp : tempPage.getRecords()) {
                ${entity}Response response = new ${entity}Response();
                BeanUtils.copyPropertiesIgnoreNull(temp, response);
                responseList.add(response);
            }
        }
        result.setRecords(responseList);

        return result;
    }

    /**
     * ${table.comment!} 下拉框
     * @return
     */
    //@Cacheable(cacheNames = ${cacheName}, key = "'ALL'")
    public List<${entity}Response> options(){
        QueryWrapper<${entity}> queryWrapper = new BaseRequest<${entity}>().getQueryWrapper(${entity}.class);
        List<${entity}> list = ${entity?uncap_first}Service.list(queryWrapper);
        List<${entity}Response> result;
        if (!CollectionUtils.isEmpty(list)){
            result = new ArrayList<>(list.size());
            for (${entity} temp : list) {
                ${entity}Response response = new ${entity}Response();
                BeanUtils.copyPropertiesIgnoreNull(temp, response);
                result.add(response);
            }
        }else{
            result = new ArrayList<>(0);
        }
        return result;
    }
</#if>
<#if table.fields!?size gt cfg.minExport && !hasChild>
    public List<${entity}Response> export(BaseRequest<${entity}> request) {
        List<${entity}> list = ${entity?uncap_first}Service.list(request.getQueryWrapper());
        List<${entity}Response> responseList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
    <#list table.fields as field>
        <#if field.propertyName?ends_with("Id") && field.propertyType == "Integer">
            List<${field.propertyName?cap_first?replace("Id","")}Response> ${field.propertyName?replace("Id","")}List  = ${(field.propertyName)?replace("Id","")}SupportService.options();
            Map<${cfg.idType}, String> ${field.propertyName?replace("Id","")}Map = ${field.propertyName?replace("Id","")}List.stream().collect(Collectors.toMap(${field.propertyName?cap_first?replace("Id","")}Response::getId,${field.propertyName?cap_first?replace("Id","")}Response::getName));

        </#if>
    </#list>
            for (${entity} temp : list) {
                ${entity}Response response = new ${entity}Response();
                BeanUtils.copyPropertiesIgnoreNull(temp, response);
    <#list table.fields as field>
        <#if field.propertyName?ends_with("Id") && field.propertyType == "Integer">
                response.set${field.propertyName?cap_first?replace("Id","Name")}(${field.propertyName?replace("Id","")}Map.getOrDefault(temp.get${field.propertyName?cap_first}(), ""));
        </#if>
    </#list>
                responseList.add(response);
            }
        }
        return responseList;
    }

    public void importData(List<Map<String, Object>> data) {
        if (!CollectionUtils.isEmpty(list)) {
    <#list table.fields as field>
        <#if field.propertyName?ends_with("Id") && field.propertyType == "Integer">
            List<${field.propertyName?cap_first?replace("Id","")}Response> ${field.propertyName?replace("Id","")}List  = ${(field.propertyName)?replace("Id","")}SupportService.options();
            Map<String, ${cfg.idType}> ${field.propertyName?replace("Id","")}Map = ${field.propertyName?replace("Id","")}List.stream().collect(Collectors.toMap(${field.propertyName?cap_first?replace("Id","")}Response::getName), ${field.propertyName?cap_first?replace("Id","")}Response::getId);

        </#if>
    </#list>
            List<${entity}> list = new ArrayList<>(data.size());
            for (Map<String, Object> map : data) {
                ${entity} temp = new ${entity}();
    <#list table.fields as field>
        <#if field.propertyType == "Stirng">
                temp.set${field.propertyName?cap_first}(String.valueOf(map.get("${field.comment}")).trim());
        <#elseif !field.propertyName?ends_with("Id")>
            <#if field.propertyType == "Integer">
                temp.set${field.propertyName?cap_first}(Integer.valueOf(String.valueOf(map.get("${field.comment}")).trim()));
            <#elseif field.propertyType == "Long">
                temp.set${field.propertyName?cap_first}(Long.valueOf(String.valueOf(map.get("${field.comment}")).trim()));
            <#elseif field.propertyType == "Double">
                temp.set${field.propertyName?cap_first}(Long.valueOf(Double.valueOf(map.get("${field.comment}")).trim()));
            <#elseif field.propertyType == "BigDecimal">
                temp.set${field.propertyName?cap_first}(new BigDecimal(String.valueOf(map.get("${field.comment}")).trim()));
            </#if>
        </#if>

    </#list>
    <#list table.fields as field>
        <#if field.propertyName?ends_with("Id") && field.propertyType == "Integer">
                String ${field.propertyName?replace("Id","")}Name = String.valueOf(map.get("${field.comment}"));
                Integer ${field.propertyName} = ${field.propertyName?replace("Id","")}Map.get(${field.propertyName?replace("Id","")}Name);
                if (null == ${field.propertyName}) {
                    ${field.propertyName?replace("Id","")}Request ${field.propertyName?replace("Id","")?uncap_first}Request = new ${field.propertyName?replace("Id","")}Request();
                    ${field.propertyName?replace("Id","")?uncap_first}Request.setName(${field.propertyName?replace("Id","")}Name);
                    ${field.propertyName?replace("Id","")}Response ${field.propertyName?replace("Id","")?uncap_first}Response = ${(field.propertyName)?replace("Id","")}SupportService.save(${field.propertyName?replace("Id","")?uncap_first}Request);
                    ${field.propertyName?replace("Id","")}Map.put(${field.propertyName?replace("Id","")?uncap_first}Response.getName(), ${field.propertyName?replace("Id","")?uncap_first}Response.getId());
                    ${field.propertyName} = ${field.propertyName?replace("Id","")?uncap_first}Response.getId();
                }
                temp.set${field.propertyName?cap_first}(${field.propertyName});

        </#if>
    </#list>
                list.add(temp);
            }
        }
        ${entity?uncap_first}Service.saveBatch(list);
    }
</#if>
<#if hasStatus>
    //@CacheEvict(cacheNames = ${cacheName}, allEntries = true)
    public void status(${cfg.idType} id,Integer status) {
        ${entity} temp = new ${entity}();
        temp.setId(id);
        temp.setStatus(status);
        ${entity?uncap_first}Service.updateById(temp);
    }
</#if>

    //@Cacheable(cacheNames = ${cacheName}, unless="#result == null", key = "#id")
    public ${entity}Response getOne(${cfg.idType} id) {
        ${entity} temp = ${entity?uncap_first}Service.getById(id);
        if (null == temp) {
            return null;
        }
        ${entity}Response result = new ${entity}Response();
        BeanUtils.copyPropertiesIgnoreNull(temp, result);
        return result;
    }
<#if hasSort>
    //@CacheEvict(cacheNames = ${cacheName}, allEntries = true)
    @Transactional(rollbackFor = {BizException.class}, propagation = Propagation.REQUIRED)
    public void sort(BaseSortChange request) {
        ${entity} temp1 = new ${entity}();
        temp1.setId(request.getOneId());
        temp1.setSortBy(request.getTwoSortBy());
        ${entity} temp2 = new ${entity}();
        temp2.setId(request.getTwoId());
        temp2.setSortBy(request.getOneSortBy());
        ${entity?uncap_first}Service.updateById(temp1);
        ${entity?uncap_first}Service.updateById(temp2);
    }
</#if>

    //@CacheEvict(cacheNames = ${cacheName}, allEntries = true)
    //@Lockable(lockName = ${cacheName} + "_LOCK_INSERT", key = "#request.toString")
    public ${entity}Response save(${entity}Request request) {
        ${entity} temp = new ${entity}();
        BeanUtils.copyPropertiesIgnoreNull(request, temp);
        <#if hasSort>temp.setSortBy(${entity?uncap_first}Service.count()));</#if>
        temp.setCreateTime(LocalDateTime.now());
        ${entity?uncap_first}Service.save(temp);
        ${entity}Response result = new ${entity}Response();
        BeanUtils.copyPropertiesIgnoreNull(temp, result);
        return result;
    }

    //@CacheEvict(cacheNames = ${cacheName}, allEntries = true)
    @Lockable(lockName = ${cacheName} + "_LOCK_UPDATE", key = "#request.id")
    public void update(${entity}Request request) {
        ${entity} temp = new ${entity}();
        BeanUtils.copyPropertiesIgnoreNull(request, temp);
        ${entity?uncap_first}Service.updateById(temp);
    }
<#if hasChild>

    //@CacheEvict(cacheNames = ${cacheName}, allEntries = true)
    @Transactional(rollbackFor = {BizException.class}, propagation = Propagation.REQUIRED)
    public void remove(${cfg.idType} id) {
        Set<${cfg.idType}> ids;
        List<${entity}Response> responseList = listAll();
        if (!CollectionUtils.isEmpty(responseList)) {
            ParentEntityUtils<${entity}Response> treeUtils = new ParentEntityUtils<>(responseList);
            ids = treeUtils.getChildIds(id);
        } else {
            ids = new HashSet<>();
        }
        ids.add(id);
        ${entity?uncap_first}Service.removeByIds(ids);
    }
<#else>

    //@CacheEvict(cacheNames = ${cacheName}, allEntries = true)
    public void remove(${cfg.idType} id) {
        ${entity?uncap_first}Service.removeById(id);
    }
</#if>

}